#include "widget.h"
#include "config.h"
#include <QIcon>
#include <QPainter>
#include <QMouseEvent>
#include <ctime>
#include <QLabel>
#include <QFont>
#include <pause.h>
#include "lives.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent),m_score(0),m_pause(false),m_gameover(false)
{
    initscene();
    playGame();
}

Widget::~Widget()
{}

void Widget::initscene()
{
    setFixedSize(gamewidth,gameheight);
    setWindowTitle(title);
    setWindowIcon(QIcon(gameicon));
    m_Timer.setInterval(gamerate);
    m_recorder=0;
    srand((unsigned int)time(NULL));
    m_Pause.m_Rect.moveTo(gamewidth - m_Pause.m_Rect.width(), 0);

    int buttonx=(gamewidth - restartbutton.restart_rect.width()) / 2;
    int buttony = gameheight / 2 + 150;
    restartbutton.setRestartButtonPosition(buttonx, buttony);
}

void Widget::playGame()
{
    m_Timer.start();
    connect(&m_Timer,&QTimer::timeout,[=](){
        if(!m_pause&&!m_gameover)
        {
        enemyToscene();
        updatePosition();
        collisionDetection();
        update();
        }
    });
}

void Widget::updatePosition()
{
    m_map.mapPosition();
    m_hero.shoot();
    for(int i=0;i<BULLET_NUM;i++)
    {
        if(m_hero.m_bullets[i].m_Free==false)
        {
            m_hero.m_bullets[i].updatePosition();
        }
    }
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free==false)
        {
            m_enemys[i].updatePosition();
        }
    }
    for(int i=0;i<ENEMY2_NUM;i++)
    {
        if(m_enemys2[i].m_Free==false)
        {
            m_enemys2[i].updatePosition();
        }
    }
    for(int i=0;i<BOMBNUM;i++)
    {
        if(m_bombs[i].m_Free==false)
        {
            m_bombs[i].updateInfo();
        }
    }
    for(int i=0;i<ENEMY2_BOMB_NUM;i++)
    {
        if(m_bombs2[i].m_Free2==false)
        {
            m_bombs2[i].updateInfo2();
        }
    }
}


void Widget::paintEvent(QPaintEvent *)
{
    QPixmap buffer(size());
    QPainter bufferPainter(&buffer);

    bufferPainter.drawPixmap(0, m_map.m_map1_posY, m_map.m_map1);
    bufferPainter.drawPixmap(0, m_map.m_map2_posY, m_map.m_map2);

    if(m_hero.m_Destroy)
    {
        m_hero.m_counter++;
        if (m_hero.m_counter >= m_hero.m_interval) {
            m_hero.m_destroyFrame++;
            if (m_hero.m_destroyFrame >= 4) {
                m_hero.m_Destroy = false;
                m_hero.m_destroyFrame = 0;
            }
            m_hero.m_counter = 0;
        }
    }
    if (m_hero.m_Destroy) {
        if (m_hero.m_destroyFrame < 4) {
            bufferPainter.drawPixmap(m_hero.m_x, m_hero.m_y, m_hero.m_destroyPixmaps[m_hero.m_destroyFrame]);
        }
    } else if(!m_gameover){
        bufferPainter.drawPixmap(m_hero.m_x, m_hero.m_y, m_hero.m_plane);
        update();
    }

    for (int i = 0; i < BULLET_NUM; i++)
    {
        if (m_hero.m_bullets[i].m_Free == false)
        {
            bufferPainter.drawPixmap(m_hero.m_bullets[i].m_x, m_hero.m_bullets[i].m_y, m_hero.m_bullets[i].m_Bullet);
        }
    }
    for (int i = 0; i < ENEMY_NUM; i++)
    {
        if (m_enemys[i].m_Free == false)
        {
            bufferPainter.drawPixmap(m_enemys[i].m_x, m_enemys[i].m_y, m_enemys[i].m_enemy);
        }
    }
    for (int i = 0; i < ENEMY2_NUM; i++) {
        if (m_enemys2[i].m_Free == false)
        {
            bufferPainter.drawPixmap(m_enemys2[i].m_x, m_enemys2[i].m_y, m_enemys2[i].m_enemy);
        }
    }
    for (int i = 0; i < BOMBNUM; i++)
    {
        if (m_bombs[i].m_Free == false)
        {
            bufferPainter.drawPixmap(m_bombs[i].m_x, m_bombs[i].m_y, m_bombs[i].m_pixArr[m_bombs[i].m_index]);
        }
    }
    for(int i=0;i<ENEMY2_BOMB_NUM;i++)
    {
        if(m_bombs2[i].m_Free2==false)
        {
            bufferPainter.drawPixmap(m_bombs2[i].m_x2, m_bombs2[i].m_y2, m_bombs2[i].m_pixArr2[m_bombs2[i].m_index2]);
        }
    }
    bufferPainter.setPen(Qt::black);
    bufferPainter.setFont(QFont("幼圆", wordsize));
    bufferPainter.drawText(10, 30, QString("分数：%1").arg(m_score));
    if (m_pause)
    {
        bufferPainter.drawPixmap(m_Pause.m_Rect.x(), m_Pause.m_Rect.y(), m_Pause.m_resume);
    }
    else
    {
        bufferPainter.drawPixmap(m_Pause.m_Rect.x(), m_Pause.m_Rect.y(), m_Pause.m_pause);
    }
    m_lives.draw(bufferPainter);

    if (m_hero.m_Destroy == false && m_lives.leftLives() == 0)
    {
        m_gameover = true;
        m_Timer.stop();
        bufferPainter.setPen(Qt::black);
        bufferPainter.setFont(QFont("幼圆", 48));
        bufferPainter.drawText(gamewidth / 2 - 125, gameheight / 2-50, "游戏结束");
        bufferPainter.drawText(gamewidth / 2 - 150, gameheight / 2 + 50, QString("本次分数:%1").arg(m_score));
        bufferPainter.drawPixmap(gamewidth / 2-restartbutton.restart_rect.width()*0.5, gameheight / 2+100, restartbutton.restartbutton);
    }

    QPainter painter(this);
    painter.drawPixmap(0, 0, buffer);
}

void Widget::mouseMoveEvent(QMouseEvent * event)
{
    if(!m_hero.m_control) return;
    int x=event->x()-m_hero.m_Rect.width()*0.5;
    int y=event->y()-m_hero.m_Rect.height()*0.5;
    if(x<=0)
    {
        x=0;
    }
    if(x>=gamewidth-m_hero.m_Rect.width())
    {
        x=gamewidth-m_hero.m_Rect.width();
    }
    if(y<=0)
    {
        y=0;
    }
    if(y>=gameheight-m_hero.m_Rect.height())
    {
        y=gameheight-m_hero.m_Rect.height();
    }
    m_hero.MoveTo(x,y);
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    if(!m_hero.m_control) return;
    int x=m_hero.m_x;
    int y=m_hero.m_y;
    if (m_gameover || m_pause) return;
    else{
        switch(event->key())
        {
        case Qt::Key_A:
            x -= m_hero.m_speed;
            break;
        case Qt::Key_D:
            x += m_hero.m_speed;
            break;
        case Qt::Key_W:
            y -= m_hero.m_speed;
            break;
        case Qt::Key_S:
            y +=m_hero.m_speed;
        }
        if(x<=0)
        {
            x=0;
        }
        if(x>=gamewidth-m_hero.m_Rect.width())
        {
            x=gamewidth-m_hero.m_Rect.width();
        }
        if(y<=0)
        {
            y=0;
        }
        if(y>=gameheight-m_hero.m_Rect.height())
        {
            y=gameheight-m_hero.m_Rect.height();
        }
        m_hero.MoveTo(x,y);
    }
}

void Widget::enemyToscene()
{
    m_recorder++;
    if(m_recorder<ENEMY_INTERVAL)
    {
        return;
    }
    m_recorder=0;
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free)
        {
            m_enemys[i].m_Free=false;
            m_enemys[i].m_x=rand()%(gamewidth-m_enemys[i].m_Rect.width());
            m_enemys[i].m_y=-m_enemys[i].m_Rect.height();
            break;
        }
    }
    m_enemy2Recorder++;
    if (m_enemy2Recorder < ENEMY2_INTERVAL) return;
    m_enemy2Recorder = 0;

    for (int j = 0; j < ENEMY2_NUM; j++) {
        if (m_enemys2[j].m_Free) {
            m_enemys2[j].m_Free = false;
            m_enemys2[j].m_x = rand() % (gamewidth - m_enemys2[j].m_Rect.width());
            m_enemys2[j].m_y = -m_enemys2[j].m_Rect.height();
            break;
        }
    }
}

void Widget::collisionDetection()
{
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free)
        {
            continue;
        }

        for(int j=0;j<BULLET_NUM;j++)
        {
            if(m_hero.m_bullets[j].m_Free)
            {
                continue;
            }

            if(m_enemys[i].m_Rect.intersects(m_hero.m_bullets[j].m_Rect))
            {
                m_enemys[i].m_Free=true;
                m_hero.m_bullets[j].m_Free=true;
                for(int k=0;k<BOMBNUM;k++)
                {
                    if(m_bombs[k].m_Free)
                    {
                        m_bombs[k].m_Free=false;
                        m_bombs[k].m_x=m_enemys[i].m_x;
                        m_bombs[k].m_y=m_enemys[i].m_y;
                        break;
                    }
                }
                m_score++;
            }
        }
        if (m_enemys[i].m_Rect.intersects(m_hero.m_Rect)) {
            m_enemys[i].m_Free = true;
            for (int k = 0; k < BOMBNUM; k++) {
                if (m_bombs[k].m_Free) {
                    m_bombs[k].m_Free = false;
                    m_bombs[k].m_x = m_enemys[i].m_x;
                    m_bombs[k].m_y = m_enemys[i].m_y;
                    break;
                }
            }
            m_lives.decreaseLife();
            if (m_lives.leftLives() <= 0)
            {
                m_hero.m_Destroy=true;
                m_hero.m_destroyFrame=0;
                m_hero.m_counter=0;
                m_hero.m_control=false;
            }
    }
  }
    for (int i = 0; i < ENEMY2_NUM; i++) {
        if (m_enemys2[i].m_Free) continue;

        for (int j = 0; j < BULLET_NUM; j++) {
            if (m_hero.m_bullets[j].m_Free) continue;
            if (m_enemys2[i].m_Rect.intersects(m_hero.m_bullets[j].m_Rect)) {
                m_enemys2[i].hit();
                m_hero.m_bullets[j].m_Free = true;
                if (m_enemys2[i].isDead()) {
                    m_enemys2[i].m_Free = true;
                    for(int k=0;k<ENEMY2_BOMB_NUM;k++)
                    {
                        if(m_bombs2[k].m_Free2)
                        {
                            m_bombs2[k].m_Free2=false;
                            m_bombs2[k].m_x2=m_enemys2[i].m_x;
                            m_bombs2[k].m_y2=m_enemys2[i].m_y;
                            break;
                        }
                    }
                    m_score += 2;
                }
            }
        }
        if (m_enemys2[i].m_Rect.intersects(m_hero.m_Rect)) {
            m_enemys2[i].m_Free = true;
            m_lives.decreaseLife();
        }
    }
}
void Widget::mousePressEvent(QMouseEvent *event)
{
    restartbutton.setRestartButtonPosition(gamewidth / 2-restartbutton.restart_rect.width()*0.5, gameheight / 2+100);
    if (m_Pause.m_Rect.contains(event->pos())) {
        m_pause = !m_pause;
        if (m_pause) {
            m_Timer.stop();
        } else {
            m_Timer.start();
        }
        update();
    }
    if (m_gameover) {
        if (restartbutton.restart_rect.contains(event->pos())) {
            restart();
        }
    }
}

void Widget::restart()
{
    m_score = 0;
    m_pause = false;
    m_gameover = false;
    m_lives.m_lives=3;
    m_hero.MoveTo(gamewidth*0.5-m_hero.m_Rect.width()*0.5,gameheight-m_hero.m_Rect.height());

    for (int i = 0; i < ENEMY_NUM; i++) {
        m_enemys[i].m_Free = true;
    }
    for (int i = 0; i < BULLET_NUM; i++) {
        m_hero.m_bullets[i].m_Free = true;
    }
    for (int i = 0; i < BOMBNUM; i++) {
        m_bombs[i].m_Free = true;
    }
    for (int i = 0; i < ENEMY2_NUM; i++) {
        m_enemys2[i].m_Free = true;
        m_enemys2[i].m_hitCount = 0;
    }
    m_enemy2Recorder = 0;
    m_hero.m_control=true;
    m_Timer.start();
    update();
}
